﻿using System;
using System.Linq;
using MadLibrary.Collections;
namespace MadLibrary.Managing.Tasks
{
    /// <summary>
    /// Holds and manages collection of tasks.
    /// </summary>
    public class Tasks : Collection<Task>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Tasks"/> class.
        /// </summary>
        public Tasks()
            : base()
        {

        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Tasks"/> class.
        /// </summary>
        /// <param name="Tasks">The tasks.</param>
        public Tasks(params Task[] Tasks)
            : base(Tasks)
        {

        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Tasks"/> class.
        /// </summary>
        /// <param name="Tasks">The tasks.</param>
        public Tasks(Tasks Tasks)
            : base(Tasks)
        {

        }
        /// <summary>
        /// Get tasks with hightest priority.
        /// </summary>
        /// <returns>Task with hightest priority.</returns>
        public Task[] GetHightestPriority()
        {
            var highestPriorityTask = data.OrderByDescending(t => t.Priority).FirstOrDefault();

            return
                highestPriorityTask == null
                    ? null
                    : data.Where(t => t.Priority == highestPriorityTask.Priority).ToArray();
        }
        /// <summary>
        /// Get tasks with lowest priority.
        /// </summary>
        /// <returns>Task with lowest priority.</returns>
        public Task[] GetLowestPriority()
        {
            var lowestPriorityTask = data.OrderBy(t => t.Priority).FirstOrDefault();

            return
                lowestPriorityTask == null
                    ? null
                    : data.Where(t => t.Priority == lowestPriorityTask.Priority).ToArray();
        }
        /// <summary>
        /// Removes tasks which have been done.
        /// </summary>
        public void RemoveDoneTasks()
        {
            var doneTasks = this.Where(t => t.Status == TaskStatus.Done).ToArray();

            foreach (var doneTask in doneTasks)
            {
                Remove(doneTask);
            }
        }
        /// <summary>
        /// Removes tasks which have not been done.
        /// </summary>
        public void RemoveUndoneTasks()
        {
            var undoneTasks = this.Where(t => t.Status != TaskStatus.Done).ToArray();

            foreach (var undoneTask in undoneTasks)
            {
                Remove(undoneTask);
            }
        }
        /// <summary>
        /// Get undone tasks that have excided their estimated end date.
        /// </summary>
        /// <param name="relativeThreshold">The relative threshold date which the tasks should have been done before.</param>
        /// <returns>Undone tasks that have excided their estimated end date.</returns>
        public Task[] GetUndoneExcidedEstimatedEndTasks(DateTime relativeThreshold)
        {
            return data.Where(t => t.EstimatedEnd.HasValue && t.EstimatedEnd.Value < relativeThreshold).ToArray();
        }
        /// <summary>
        /// Get undone tasks without an estimated end date.
        /// </summary>
        /// <returns>Undone tasks without an estimated end date.</returns>
        public Task[] GetUndoneNoEstimatedEndTasks()
        {
            return data.Where(t => !t.EstimatedEnd.HasValue).ToArray();
        }
    }
}
